package com.cwnu.sw.cys.core.user.config;

import com.cwnu.sw.cys.core.user.service.handler.LogHandler;
import com.cwnu.sw.cys.core.user.service.handler.MsgHandler;
import com.cwnu.sw.cys.core.user.service.handler.ScanHandler;
import com.cwnu.sw.cys.core.user.service.handler.SubscribeHandler;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.stream.Collectors;

import static me.chanjar.weixin.common.api.WxConsts.EventType.SUBSCRIBE;
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType.EVENT;


/**
 * 微信公众号配置类，用于初始化微信服务和消息路由。
 *
 * @author jisam
 */
@AllArgsConstructor
@Configuration
@EnableConfigurationProperties(WxMpProperties.class)
public class WxMpConfiguration {
    private final LogHandler logHandler;
    private final MsgHandler msgHandler;
    private final SubscribeHandler subscribeHandler;
    private final ScanHandler scanHandler;
    private final WxMpProperties properties;

    /**
     * 创建并初始化微信公众号服务实例。
     *
     * @return 初始化后的微信公众号服务实例
     */
    @Bean
    public WxMpService wxMpService() {
        // 获取微信公众号配置列表
        final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
        // 如果配置列表为空，则抛出运行时异常
        if (configs == null) {
            throw new RuntimeException("请先阅读项目首页的说明（readme文件），添加相关配置，注意不要配错！");
        }

        // 创建微信公众号服务实例
        WxMpService service = new WxMpServiceImpl();
        // 设置多配置存储，使用流式处理将配置列表映射为配置存储映射
        service.setMultiConfigStorages(configs
                .stream().map(a -> {
                    // 创建默认配置实现实例
                    WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();

                    // 设置应用ID
                    configStorage.setAppId(a.getAppId());
                    // 设置应用密钥
                    configStorage.setSecret(a.getSecret());
                    // 设置Token
                    configStorage.setToken(a.getToken());
                    // 设置AES密钥
                    configStorage.setAesKey(a.getAesKey());
                    return configStorage;
                }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
        // 返回微信公众号服务实例
        return service;
    }

    /**
     * 创建并初始化微信消息路由器。
     *
     * @param wxMpService 已初始化的微信服务实例
     * @return 初始化后的微信消息路由器
     */
    @Bean
    public WxMpMessageRouter messageRouter(WxMpService wxMpService) {
        final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);

        // 设置日志处理的全局规则，对所有消息进行日志记录
        newRouter.rule().handler(this.logHandler).next();

        // 配置订阅事件的处理规则，异步处理设置为false表示同步处理
        // 仅处理EVENT类型的消息中的SUBSCRIBE事件
        // 使用subscribeHandler进行订阅事件的处理
        newRouter.rule().async(false).msgType(EVENT).event(SUBSCRIBE).handler(this.subscribeHandler).end();

        // 配置扫描关注事件的处理规则，异步处理设置为false表示同步处理
        // 仅处理EVENT类型的消息中的SCAN事件
        // 使用scanHandler进行扫描关注事件的处理
        newRouter.rule().async(false).msgType(EVENT).event(WxConsts.EventType.SCAN).handler(this.scanHandler).end();

        // 配置默认的消息处理规则，异步处理设置为false表示同步处理
        // 用于处理所有类型的消息
        // 使用msgHandler进行消息的处理
        newRouter.rule().async(false).handler(this.msgHandler).end();
        return newRouter;
    }

}
